package servlet;

import java.io.File;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.util.*;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

import service.*;
import util.*;

import domain.Actor;
import domain.User;
import ex.DatabaseException;
import ex.RegistrationFailedException;


public class Register extends HttpServlet {
	UserService userService=new UserService();
	ActorService actorService=new ActorService();
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
		request.setCharacterEncoding("UTF-8");
		List<Title> titles=TitleUtil.getTitles();
		request.setAttribute("titles",titles);

		RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
		if (dispatcher != null) 
			dispatcher.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try{
			request.setCharacterEncoding("UTF-8");
			// Create a factory for disk-based file items
			FileItemFactory factory = new DiskFileItemFactory();
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);
			// Parse the request
			List<FileItem> items = upload.parseRequest(request); 
			Map<String, String> fieldMap = new HashMap<String, String>();
			// Process the uploaded items
			Iterator<FileItem> iter = items.iterator();
			String destination = "";
			while (iter.hasNext()) {
				FileItem item = (FileItem) iter.next();
				if(item.isFormField()){
					String value=item.getString("UTF-8").trim();
					if(item.getFieldName().equalsIgnoreCase("title") && fieldMap.containsKey("title") ){
						value=value+"#" +fieldMap.get("title");
					}
					fieldMap.put(item.getFieldName(),value );
				}else{
					String fileName="/" + fieldMap.get("email") + ".jpeg";
					destination = getServletContext().getRealPath("/jsp/user/images/user"+ fileName);
					File uploadedFile = new File(destination);
					item.write(uploadedFile);
					destination=ExpindConstants.rootPath + "/jsp/user/images/user"+ fileName;
				}
			}
			String email=fieldMap.get("email");
			String firstName=fieldMap.get("firstname");
			String surname=fieldMap.get("surname");
			String password=fieldMap.get("password");
			String password2=fieldMap.get("password2");
			boolean	female=!fieldMap.get("gender").equalsIgnoreCase("male");
			//String image=request.getParameter("image");
			String imageURL=destination;			
			Date birthDate=getDate(fieldMap);
			String city=fieldMap.get("city");
			String tel=fieldMap.get("tel");
			String description=fieldMap.get("description");

			Actor actor = null;
			//storing what titles the user has marked through bitwise operation
			int titleBits = getTitleBits(fieldMap.get("title"));
			if(titleBits!=-1){

				boolean actorSelected=(titleBits & TitleUtil.actor_bit)==TitleUtil.actor_bit;

				if(actorSelected){
					String heightString=fieldMap.get("height");
					int height=0;
					if(!RegexUtil.isParsableToInt(heightString)){
						throw new RegistrationFailedException("Height is not in correct format!");
					}
					else{
						height=Integer.parseInt(heightString);
					}
					String weightString=fieldMap.get("weight");
					int weight=0;
					if(!RegexUtil.isParsableToInt(weightString)){
						throw new RegistrationFailedException("Weight is not in correct format!");
					}
					else{
						weight=Integer.parseInt(weightString);
					}
					String hairColor=fieldMap.get("hair");
					String skinColor=fieldMap.get("skin");
					String eyeColor=fieldMap.get("eyes");
					actor=new Actor(-1, hairColor, eyeColor,skinColor, height, weight);
				}
			}
			User user=new User((long)-1,email,password,firstName,surname,birthDate, imageURL,description,city,tel, titleBits, 0, 0, actor,true, true, female);
			userService.createUser(user,password2);
			user= userService.authenticateUser(user.getEmail(), user.getPassword());

			HttpSession session = request.getSession();
			session.setAttribute("user", user);

			response.sendRedirect("user?who=me");


		}
		catch (RegistrationFailedException e) {
			List<Title> titles=TitleUtil.getTitles();
			request.setAttribute("titles",titles);
			request.setAttribute("registerError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (DatabaseException e) {
			List<Title> titles=TitleUtil.getTitles();
			request.setAttribute("titles",titles);
			request.setAttribute("registerError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (ParseException e) {
			List<Title> titles=TitleUtil.getTitles();
			request.setAttribute("titles",titles);
			request.setAttribute("registerError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}catch (FileUploadException e) {
			List<Title> titles=TitleUtil.getTitles();
			request.setAttribute("titles",titles);
			request.setAttribute("registerError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (Exception e) {
			List<Title> titles=TitleUtil.getTitles();
			request.setAttribute("titles",titles);
			request.setAttribute("registerError", "A general error occured:" + e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/register.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
	}

	protected Date getDate(Map<String, String> fieldMap) throws ParseException{
		String day= fieldMap.get("day");
		String month=fieldMap.get("month");
		String year=fieldMap.get("year");

		String datetimeString=year+" " + month + " " + day;
		return DateUtil.convertStringToDateYYYYMMDD(datetimeString);
	}

	protected int getTitleBits(String titleNames) throws ParseException{
		String[] titles = RegexUtil.splitDiyez(titleNames);

		//storing what titles the user has marked through bitwise operation
		int titleBits = 0x00;
		if (titles != null) {
			Title title;
			for (int i = 0; i < titles.length; i++)	{
				String value=titles[i];
				if(!RegexUtil.isNullOrEmpty(value)){
					title=TitleUtil.getTitleByTitleName(value);
					if(title!=null){
						titleBits |= title.getTitleBit();
					}
				}
			}
			return titleBits;
		}
		return 0;
	}
}
